package com.ok.es.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.ok.common.domain.po.Result;
import com.ok.es.domain.po.OkCard;
import com.ok.es.domain.po.OkCartoon;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @ClassName CardEsContrller
 * @Description 帖子es查询
 * @Author hw
 * @Date 2024/5/15 15:25
 */
@Api(tags = "帖子es接口")
@RestController
@RequestMapping("/card-es")
public class CardEsController {

    @Autowired
    private RestHighLevelClient client;

    @ApiOperation("*搜索帖子")
    @GetMapping("/list")
    public Result list(@RequestParam Integer pageNo,
                       @RequestParam Integer pageSize,
                       @RequestParam(required = false) String title,
                       @RequestParam(required = false) Integer categoryId) throws IOException {

        //创建Request
        SearchRequest request = new SearchRequest("card");
        // 2.组织请求参数
        // 2.1.准备bool查询
        BoolQueryBuilder bool = QueryBuilders.boolQuery();
        if (title!=null || categoryId !=null){
            if (title!=null){
                bool.should(QueryBuilders.matchQuery("title",title));
                bool.should(QueryBuilders.matchQuery("content",title));

            }
            if (categoryId !=null){
                bool.must(QueryBuilders.termQuery("categoryId",categoryId));
            }
        }
        //创建一个高亮对象
        HighlightBuilder highlightBuilder = SearchSourceBuilder.highlight();
        //高亮条件
        request.source().highlighter(highlightBuilder.field("title"));
        request.source().highlighter(highlightBuilder.field("content"));
        //分页
        request.source().from((pageNo - 1) * pageSize).size(pageSize);
        //加入构建的查询条件
        request.source().query(bool);
        //发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        List list = handleResponse(response);

        return Result.success(list);
    }


    /*
    解析响应
     */
    private List handleResponse(SearchResponse response) {
        ArrayList<Object> list = new ArrayList<>();
        SearchHits searchHits = response.getHits();
        // 1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 2.遍历结果数组
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            // 3.得到_source，也就是原始json文档
            String source = hit.getSourceAsString();
            // 4.反序列化并打印
            OkCard item = JSONUtil.toBean(source, OkCard.class);

            //获取高亮结果
            Map<String, HighlightField> hfs = hit.getHighlightFields();
            if (!CollUtil.isEmpty(hfs)) {
                //有高亮结果，获取title的高亮结果
                HighlightField hf = hfs.get("title");
                if (hf != null) {
                    //获取第一个高亮结果片段，就是商品名称的高亮值
                    String hfName = hf.getFragments()[0].toString();
                    item.setTitle(hfName);
                }
                HighlightField hf2 = hfs.get("content");
                if (hf2 != null) {
                    //获取第一个高亮结果片段，就是商品名称的高亮值
                    String hf2Name = hf2.getFragments()[0].toString();
                    item.setContent(hf2Name);
                }
            }
            System.out.println(item);
            list.add(item);
        }
        return list;
    }
}
